package cn.itcast.web.action;

import cn.itcast.domain.base.Courier;
import cn.itcast.service.CourierService;
import cn.itcast.utils.ResponseUtils;
import com.alibaba.fastjson.JSONArray;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;

import javax.persistence.criteria.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Namespace("/")
@ParentPackage("json-default")
@Controller
@Scope("prototype")
public class CourierAction extends ActionSupport implements ModelDriven<Courier> {
    private Courier courier = new Courier();//属性驱动

    @Override
    public Courier getModel() {
        return courier;
    }

    @Autowired
    private CourierService courierService;
    private Integer page;//当前页
    private Integer rows;//每页记录数

    public void setPage(Integer page) {
        this.page = page;
    }

    public void setRows(Integer rows) {
        this.rows = rows;
    }

    // 复杂条件查询
    @Action(value = "courier_save", results = {@Result(name = "success", location = "./pages/base/courier.html", type = "redirect")})
    public String save() {
        courierService.save(courier);
        return SUCCESS;
    }

    @Action(value = "courier_pageQuery")
    public void findAll() {
        //构造条件查询
        Specification<Courier> specification = new Specification<Courier>() {
            /*  return null 则表示无条件查询
             courierRoot:当前目标类所对应的table
             query:构造简单条件并返回 相当于where
             cb:条件对象,构造复杂条件
             条件查询相关参数
             当前表 :courierNum  工号 精确查询
                    company    公司 模糊查询
                    type      快递员类型 精确查询
             关联表 :standard.name 收派标准 模糊查询

             1 先处理当前表数据 构造复杂条件
             2 再处理关联表数据 构造复杂条件
             3 整合条件
            */
            @Override
            public Predicate toPredicate(Root<Courier> courierRoot, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = new ArrayList<>();
                //对参数进行非空判断
                if (StringUtils.isNotBlank(courier.getCourierNum())) {
                    /* cb.equal :表示参数构造的条件关系 like lt gt ....
                    参数1:对应字段在entity类中的属性的class对象
                    参数2:页面传过来的参数 可以进行字符串拼接 对参数进行条件处理
                    解读:参数1对应的字段+cb关联的条件关系+参数2
                     where courierNum = 参数
                     */
                    Predicate p1 = cb.equal(courierRoot.<String>get("courierNum"), courier.getCourierNum());
                    predicates.add(p1);
                }
                if (StringUtils.isNotBlank(courier.getCompany())) {
                    Predicate p2 = cb.like(courierRoot.<String>get("company"), "%" + courier.getCompany() + "%");
                    //where company like 参数
                    predicates.add(p2);
                }
                if (StringUtils.isNotBlank(courier.getType())) {
                    Predicate p3 = cb.equal(courierRoot.<String>get("type"), courier.getType());
                    // where type = 参数
                    predicates.add(p3);
                }
                //对关联表进行条件处理
                //多表进行连接
                Join<Object, Object> standardRoot = courierRoot.join("standard", JoinType.INNER);
                //非空条件判断 对象不为null且 对象name属性不为空
                if (courier.getStandard() != null && StringUtils.isNotBlank(courier.getStandard().getName())) {
                    //where courier.getstandard().getName() like 参数
                    Predicate p4 = cb.like(standardRoot.<String>get("name"), "%" + courier.getStandard().getName() + "%");
                    predicates.add(p4);
                }
                return cb.and(predicates.toArray(new Predicate[0]));//定义array泛型

            }
        };


        Pageable pageable = new PageRequest(page - 1, rows);
        Page<Courier> pageData = courierService.findAll(specification, pageable);
        Map<String, Object> results = new HashMap<>();
        results.put("total", pageData.getTotalElements());
        results.put("rows", pageData.getContent());
        String json = JSONArray.toJSONString(results);
        ServletActionContext.getResponse().setContentType("text/html;charset=utf-8");
        try {
            ServletActionContext.getResponse().getWriter().write(json);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //批量作废
    private String ids;

    public void setIds(String ids) {
        this.ids = ids;
    }

    @Action(value = "courier_delBatch", results = {@Result(name = "success", location = "./pages/base/courier.html", type = "redirect")})
    public String delBatch() {
        String[] idArray = ids.split(",");
        courierService.delBatch(idArray);

        return SUCCESS;
    }

    //批量还原
    @Action(value = "courier_solBatch", results = {@Result(name = "success", location = "./pages/base/courier.html", type = "redirect")})
    public String solBatch() {
        String[] idArray = ids.split(",");
        courierService.solBatch(idArray);
        return SUCCESS;
    }

    //关联快递员查询 Set<FixedArea> fixedAreas为空 "url:'../../courier_findnoassociation.action
    @Action(value = "courier_findnoassociation")
    public String findNossociation() {
        List<Courier> couriers = courierService.findNoassociation();
        String json = JSONArray.toJSONString(couriers);
        ResponseUtils.responseWriter(json);
        return NONE;
    }

}
